package com.atguigu.lease.web.app.service.impl;



import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.common.exception.MyBusinessException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.common.utils.JWTUtil;
import com.atguigu.lease.model.entity.UserInfo;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.app.service.LoginService;
import com.atguigu.lease.web.app.service.UserInfoService;
import com.atguigu.lease.web.app.vo.user.LoginVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
   @Autowired
    StringRedisTemplate stringRedisTemplate;
   @Autowired
   Client client;
   @Autowired
    UserInfoService userInfoService;

    @Override
    public void getCode(String phone) {
        if(!StringUtils.hasText(phone))
        {
            throw new MyBusinessException(ResultCodeEnum.APP_LOGIN_PHONE_EMPTY);
        }
        String key= RedisConstant.APP_LOGIN_PREFIX+phone;
        String s = stringRedisTemplate.opsForValue().get(key);
        if(s!=null)
        {
            Long expire = stringRedisTemplate.getExpire(key);
            if(RedisConstant.APP_LOGIN_CODE_TTL_SEC-expire<RedisConstant.APP_LOGIN_CODE_RESEND_TIME_SEC)
            {
                throw new MyBusinessException(ResultCodeEnum.APP_SEND_SMS_TOO_OFTEN);
            }
        }
        String cCode=createCode(6);
      //  stringRedisTemplate.opsForValue().set(key,cCode,RedisConstant.APP_LOGIN_CODE_TTL_SEC, TimeUnit.SECONDS);
        stringRedisTemplate.opsForValue().set(key,cCode);
        sendCode(phone,cCode);
    }

    @Override
    public String login(LoginVo loginVo) {
        if(!StringUtils.hasText(loginVo.getPhone()))
        {
            throw new MyBusinessException(ResultCodeEnum.APP_LOGIN_PHONE_EMPTY);
        }
        if(!StringUtils.hasText(loginVo.getCode()))
        {
            throw new MyBusinessException(ResultCodeEnum.APP_LOGIN_CODE_EMPTY);
        }
        //查找是否存在，不存在就创建，存在就先校验账号状态，若状态是正常就直接通过验证码校验登录，不是正常就抛异常
        UserInfo one = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getPhone, loginVo.getPhone()));
        if(one!=null)
        {
            if(one.getStatus().equals(BaseStatus.DISABLE))
            {
                throw new MyBusinessException(ResultCodeEnum.APP_ACCOUNT_DISABLED_ERROR);
            }
        }
        else{
            UserInfo userInfo = new UserInfo();
            userInfo.setPhone(loginVo.getPhone());
            userInfo.setNickname("用户"+loginVo.getPhone().substring(loginVo.getPhone().length()-4));
            userInfo.setStatus(BaseStatus.ENABLE);
            one=userInfo;
            userInfoService.save(userInfo);
        }
        String key=RedisConstant.APP_LOGIN_PREFIX+loginVo.getPhone();
        String redisKey = stringRedisTemplate.opsForValue().get(key);
        if(redisKey==null)
        {
            throw new MyBusinessException(ResultCodeEnum.APP_LOGIN_CODE_EXPIRED);
        }
        if(!redisKey.equals(loginVo.getCode()))
        {
         throw new MyBusinessException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }
        //返回token
        String token = JWTUtil.createToken(one.getId(), one.getPhone());
        return token;
    }

    private String createCode(Integer length)
    {
        StringBuilder sb=new StringBuilder();
        Random random=new Random();
        for(int i=0;i<length;i++)
        {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    private void sendCode(String phone,String code) {


        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setSignName("阿里云短信测试")
                .setTemplateCode("SMS_154950909")
                .setPhoneNumbers(phone)
                .setTemplateParam("{\"code\":\""+code +"\"}");
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.sendSmsWithOptions(sendSmsRequest, runtime);
        } catch (TeaException error) {
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }


            }


        }




